perm filename MOTOR.PAL[AL,HE]1 blob
sn#290131 filedate 1977-06-28 generic text, type C, neo UTF8
COMMENT ā VALID 00009 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 .TITLE MOTOR
C00004 00003 PROGRAM INITIALIZATION
C00007 00004 INITIALIZE FOR DRIVING MOTOR
C00010 00005 START TRANSFERING BUFFER
C00012 00006 CLOCK INTERRUPT ROUTINE, START BY SENDING OFF DAC VALUES,READ THE A/D
C00016 00007 WAIT TILL DAC AND A/D ROUTINE COMPLETED, THEN UPDATE VALUES FOR NEXT TICK
C00020 00008 DAC OUTPUT INTERRUPT ROUTINE
C00022 00009 DYNAMIC RESPONSE DATA STORAGE AREA
C00026 ENDMK
Cā;
.TITLE MOTOR
.INSRT ALHEAD.PAL[AL,HE]
.=STRT11
.INSRT ARITH.PAL[AL,HE]
;DEFINITIONS:
ALARM==200 ;TRAP VECTOR FOR PANIC BUTTON
TICK==100. ;LENGTH OF TICK IN CLOCK UNITS
CMDARR==77200 ;ADDRESS OF COMMAND INPUT BUFFER FROM PDP10
JOINT ==77202 ;JOINT NUMBER TO BE DRIVEN
DC ==77204 ;DC DRIVE COMPONENT
SINAMP==77206 ;SINE AMPLITUDE
SINPER==77210 ;SINE PERIOD
DURAT ==77212 ;DURATION OF MOTION
POTTAC==77214 ;FLAG INDICATING POT OR TACH TO BE READ
MASLOC==77216 ;ADDRESS OF MASTER CHECK NUMBER FROM PDP10
MASTER==11711 ;CHECK NUMBER FROM PDP10
DAC : 174000 ;DAC SAMPLE ADDRESS
DACOUT: 174001 ;DAC VALUE REGISTER ADDRESS
BRAKES: 174002 ;DAC CONTROL INFO ADDRESS
AD : 174004 ;A/D CONTROL INFO ADDRESS
ADVAL : 174006 ;A/D SAMPLE ADDRESS
;PROGRAM INITIALIZATION
.EVEN
START: RESET
MOV #500,SP ;INITIALIZE STACK
CLR PS ;INITIALIZE PROCESSOR STATUS
CLR CLKCNT ;CLEAR CLOCK REGISTERS- TRAP RESTART
CLR CLKSET
CLR CLKS
MOV #PANIC,ALARM ;SET PANIC BUTTON TRAP TO PROPER ADDR
MOV #340,ALARM+2
MOV #DACSER,DACVEC ;SET DAC INTERRUPT SERVICE ROUTINE
MOV #340,DACVEC+2
MOV #ADCSER,ADCVEC ;SET ADC INTERRUPT SERVICE ROUTINE
MOV #300,ADCVEC+2
MOV #CLKSER,CLKTRP ;SET CLOCK INTERRUPT SERVICE ROUTINE
MOV #100,CLKTRP+2
LDFPS #0 ;SET SINGLE PRECISION FLOATING POINT
CLR MASLOC ;CLEAR MASTER NUMBER FROM PDP10
MOV #-1,CMDARR ;INDICATE READY TO RECEIVE COMMAND BLOCK FROM 10
REST: MOV #DR,DYNA ;SET POINTER TO START OF DYNAMIC RESPONSE DATA
; STORAGE AREA
CLR @DYNA ;SET THE FIRST TIME TO ZERO
MOV #-1,WRAP ;FLAG INDICATING DR BUFFER WRAPS AROUND
;WAIT LOOP LOOKING AT COMMAND BLOCK FROM PDP10
WTLP: TST KBIS ;CHECK IF ANYONE HIT VT05 KEYBOARD
BEQ .+6
JMP RUG ;BACK TO RUG IF SOMEONE CALLED
TST MASLOC ;CHECK IF COMMAND BLOCK RECEIVED FROM PDP10
BEQ WTLP ;GO LOOK AGAIN IF ZERO
CMP #MASTER,MASLOC ;CHECK IF RIGHT MASTER NUMBER FROM PDP10
BEQ SMENUM
MOV #-2,CMDARR ;SET ERROR CODE INDICATING BAD NUMBER
CLR MASLOC ;CLEAR THE BAD MASTER NUMBER
JMP REST ;GO WAIT FOR ANOTHER COMMAND BLOCK
SMENUM: CLR MASLOC
MOV #BLUE,R0 ;GET POINTER TO BLUE ARM INTERFACE ADDRESSES
TST CMDARR ;GET THE ARM NUMBER, EQUAL TO 1 IF BLUE ARM
BNE .+6 ;SKIP IF BLUE
MOV #YELO,R0 ;ELSE LOAD POINTER TO YELLOW ARM INTERFACE
MOV (R0),DAC ;STORE INTERFACE ADDRESSES
MOV (R0)+,DACOUT
INC DACOUT
MOV (R0)+,BRAKES
MOV (R0)+,AD
MOV (R0)+,ADVAL
;INITIALIZE FOR DRIVING MOTOR
MOV #7,R0 ;ZERO ALL DAC OUTPUT LEVELS
MOV #DACVAL,R1
CLRB (R1)+
SOB R0,.-2
MOV JOINT,R0 ;GET JOINT NUMBER
DEC R0 ;JOINT INDEX, GOES FROM 0 TO 6
MOV R0,JOINT ;SAVE JOINT INDEX
MOVB DC,DACVAL(R0) ;SET INITIAL DC MOTOR DRIVE VALUE, SIN(0)=0
MOV DC,D1 ;SAVE FIRST DRIVE VALUE
LDCIF SINAMP,AC0 ;FLOAT THE AMPL. OF THE SINUSOID
STF AC0,AC4 ;SAVE IT
LDCIF SINPER,AC1 ;FLOAT THE PERIOD OF THE SINUSOID
DIVF THRE60,AC1 ;DIVID BY 360 DEGREES
STF AC1,AC5
MOVB #10,@AD ;RESET ARM ERROR BITS
BITB #6,@AD ;CHECK IF MOTOR POWER NOT ON
BEQ RELBRK ;BRANCH IF POWER ON
MOV #-3,CMDARR ;ELSE SEND BACK ERROR MESSAGE
JMP REST ;EXIT
RELBRK: MOVB #20,@DAC ;RESET ARM INTERFACE
MOV #1,R1 ;GET JOINT BRAKE BIT
ASH R0,R1
BISB TACH,R1 ;OR ON TACH FEEDBACK BITS
MOV R1,@BRAKES ;RELEASE JOINT BRAKE AND SET TACH FEEDBACK
;START CLOCK ROUTINE AND WAIT TILL DONE
MOV #1,RUN ;INDICATE JOINT RUNNING
CLR TIME ;KEEP TRACK OF PRESENT TIME
MOV #4,CLKSET ;START CLOCK ROUTINE TO DRIVE JOINT
MOV #111,CLKS
MOV #TICK,CLKSET ;SET CLOCK INTERVAL
CLKLP: TST RUN ;CHECK IF DRIVING COMPLETE
BNE CLKLP ;WAIT TILL DONE
;PUT THE DYNAMIC RESPONSE DATA IN THE PROPER ORDER
ADD #2,DYNA
TST WRAP ;CHECK IF LESS THAN 500 WORDS
BMI RET ;IF WRAP STILL -1, NO WORK TO BE DONE
BGT DOESWR ;BRANCH IF THE SECOND BUFFER WRAPS AROUND
MOV #D2,FROM ;IF LESS THAN 1000, START TRANSFER FROM D2
BR TRANS ;START TRANSFERING BUFFERS
DOESWR: MOV DYNA,FROM ;FOR A WRAP AROUND, START TRANSFER FROM DYNA+2
TRANS: MOV #T2,TO ;MOVE SECOND TIME BUFFER TO T2
MOV #3,R2 ;COUNTER FOR TRANSFERING 3 BUFFERS
MOV #AG1,MAXA ;FIRST BUFFER ENDS AT AG1
;START TRANSFERING BUFFER
TRAN: MOV FROM,R0 ;PICK UP FIRST LOCATION TO BE TRANSFERED
MOV TO,R1 ;START MOVING FROM TO TO
TRA: CMP MAXA,R0 ;CHECK IF AT END OF BUFFER
BNE GOON ;SKIP IF STILL SOME LEFT
SUB #1000.,R0 ;POINT TO START OF BUFFER
GOON: MOV (R0)+,(R1)+ ;TRANSFER A WORD
CMP DYNA,R0 ;CHECK TRANSFER COMPLETED
BNE TRA
ADD #2000.,MAXA ;POINT TO THE NEXT SET OF BUFFERS
ADD #2000.,TO
ADD #2000.,FROM
ADD #2000.,DYNA
SOB R2,TRAN ;DO ALL THREE BUFFERS
;INDICATE EXECUTION COMPLETED TO PDP10
RET: CMP TIME,#2 ;CHECK IF JOINT STARTED OUT OF RANGE
BGT GODRUN ;BRANCH IF OK
MOV #-4,CMDARR ;ELSE SEND BACK ERROR MESSAGE
JMP REST ;EXIT
GODRUN: MOV #DR,R0 ;GET THE ADDRESS OF THE DYNAMIC RESPONSE DATA
ASR R0 ;GET WORD ADDRESS
NEG R0 ;COMPLEMENT TO USE AS FLAG TO TELL PDP10 WE'RE DONE
MOV R0,CMDARR
JMP REST ;GO LOOP WAITING FOR ANOTHER COMMAND BLOCK
;CLOCK INTERRUPT ROUTINE, START BY SENDING OFF DAC VALUES,READ THE A/D
CLKSER: MOV R0,-(SP) ;SAVE REGISTERS
MOV R1,-(SP)
MOV R2,-(SP)
MOV R3,-(SP)
MOV #7,NUMJT ;SET POINTERS AND COUNTER TO REFRESH DACS
MOV #DACCHN,PDAC
MOV #DACVAL,PVAL
MOVB #120,@DAC ;REFRESH DACS USING DAC INTERRUPT ROUTINE
MOV JOINT,R0 ;GET JOINT NUMBER
TST POTTAC ;CHECK IF POT OR TACH TO BE READ
BEQ .+6 ;SKIP IF POT
ADD #TACCHN-ADCCHN,R0 ;ELSE ADJUST FOR TACH CHANNEL NUMBERS
MOVB ADCCHN(R0),R1 ;GET ADC CHANNEL NUMBER
SWAB R1 ;POSITION IN UPPER HALF WORD
BIS #101,R1 ;OR "FEEL" BIT AND INTER. ENABLE ON TO CHAN #
MOV R1,@AD ;ENABLE A/D INTERRUPT ROUTINE
;SET NEXT POINTER FOR DYNAMIC RESPONSE DATA
MOV DYNA,R3 ;GET POINTER TO DYNAMIC RESPONSE DATA
ADD #2,R3 ;POINT TO THE NEXT WORD OF THE TIME BUFFER
CMP #T2,R3 ;CHECK IF AT END OF FIRST BUFFER
BNE NOTT2 ;BRANCH IF NOT END OF FIRST BUFFER
MOV #D2,R3 ;START PUTTING TIME DATA AFTER FIRST DRIVE BUFFER
INC WRAP ;INDICATE OVER 500 BLOCKS STORED
BR SETT
NOTT2: CMP #AG1,R3 ;CHECK IF AT END OF SECOND TIME BUFFER
BNE SETT ;BRANCH IF NOT END
MOV #D2,R3 ;WRAP AROUND IN SECOND BUFFER
INC WRAP ;INDICATE WRAP AROUND
;INCREMENT TIME COUNT AND COMPUTE NEXT DRIVE VALUE
SETT: INC TIME ;INCREMENT ELAPSED TIME COUNTER
MOV TIME,(R3) ;STORE TIME IN DYNA. RESPONSE AREA
MOV DC,2000.(R3) ;SET NEW MOTOR DRIVE EQUAL TO THE DC COMPONENT
TST SINAMP ;CHECK IF AMPLITUDE OF SINUSOID ZERO
BEQ NOSIN
TST SINPER ;CHECK IF PERIOD OF SINUSOID ZERO
BEQ NOSIN
CLR R0 ;CLEAR FOR DIVISION
MOV TIME,R1 ;GET THE ELAPSED TIME
DIV SINPER,R0 ;GET THE MOD OF THE SINE PERIOD AND EL.TIME
LDCIF R1,AC0 ;FLOAT THE REMAINDER
DIVF AC5,AC0 ;DIVID BY PERIOD AND CONVERT TO DEGREES
JSR PC,SNCOS ;COMPUTE SINE OF ANGLE
MULF AC4,AC0 ;MULT. THE SINE BY THE AMPLITUDE
STCFI AC0,R0 ;GET THE INTEGER PART
ADD R0,2000.(R3) ;ADD THE SINUSOID TO THE MOTOR DRIVE
;WAIT TILL DAC AND A/D ROUTINE COMPLETED, THEN UPDATE VALUES FOR NEXT TICK
NOSIN: BITB #100,@DAC ;CHECK IF DAC DONE YET
BNE CHKCLK ;BRANCH IF IT'S NOT
BITB #100,@AD ;CHECK IF A/D DONE YET
BNE CHKCLK ;BRANCH IF IT'S NOT
CMP DURAT,TIME ;CHECK IF MOTION COMPLETED
BLT JTSTOP ;BRANCH IF THIS IS THE END
MOV R3,DYNA ;ELSE UPDATE DYNAMIC RESPONSE DATA POINTER
MOV JOINT,R0 ;GET PTR TO JOINTS DAC VALUE
MOVB 2000.(R3),DACVAL(R0) ;SET ITS NEW DAC VALUE
BR CLKDNE ;EXIT CLEANLY
CHKCLK: CMP #10,CLKCNT ;CHECK IF LESS THAN 100 MICRO SECONDS LEFT
BLT NOSIN ;REPEAT CHECK IF MORE TIME LEFT
;STOP THE JOINT MOTION
JTSTOP: BIC #100,@DAC ;STOP ANY DAC OPERATIONS FROM TAKING PLACE
CLR CLKS ;STOP CLOCK
MOV #DACVAL,R0 ;ZERO ALL DAC VALUES
MOV #7,R1 ;SEVEN JOINTS IN ALL
CLRB (R0)+
SOB R1,.-2
MOV #7,NUMJT ;SET POINTERS AND COUNTER TO REFRESH DACS
MOV #DACCHN,PDAC
MOV #DACVAL,PVAL
MOVB #120,@DAC ;ZERO DACS USING DAC INTERRUPT ROUTINE
CLR @BRAKES ;TURN ON ALL OF THE JOINT BRAKES
MOV #-1,(R3) ;SET LAST TIME TO -1
MOV R3,DYNA ;SAVE PTR TO LAST DATA CELL USED
CLR RUN ;INDICATE JOINT SERVICING STOPPED
;EXIT CLOCK INTERRUPT ROUTINE CLEANLY
CLKDNE: MOV (SP)+,R3
MOV (SP)+,R2
MOV (SP)+,R1
MOV (SP)+,R0
RTI
;DAC OUTPUT INTERRUPT ROUTINE
DACSER: MOVB @PDAC,@DAC ;SET DAC CHANNEL
INC PDAC
DEC NUMJT ;CHECK IF THIS IS THE LAST CHANNEL TO OUTPUT
BLE .+10
BISB #100,@DAC ;ENABLE INTERRUPTS AGAIN IF MORE JOINTS LEFT
MOVB @PVAL,@DACOUT ;SEND OFF DAC VALUE
INC PVAL
RTI
;ANALOG TO DIGITAL CONVERTER INTERRUPT ROUTINE
ADCSER: MOV R0,-(SP) ;SAVE REGISTER
TST POTTAC ;CHECK IF TACHOMETER BEING READ
BNE SAVADC ;DON'T CHECK JOINT LIMITS IF SO
MOV JOINT,R0 ;GET INDEX TO JOINT LIMIT DATA
ASL R0
CMP @ADVAL,MINJT(R0) ;CHECK IF JOINT IN RANGE
BLT JTOTRG ;BRANCH IF JOINT OUT OF RANGE
CMP @ADVAL,MAXJT(R0) ;ELSE REPEAT FOR MAXIMUM
BLE SAVADC
JTOTRG: CLR DURAT ;INDICATE END OF JOINT SERVOING
SAVADC: MOV DYNA,R0 ;GET PTR TO DYNAMIC RESPONSE ARRAY
MOV @ADVAL,4000.(R0) ;SAVE JOINT READING
BIC #101,@AD ;TURN OFF ADC INTERRUPTS AND ALLOW A/D TO TRACK
MOV (SP)+,R0
RTI
;SEQUENCE TO FOLLOW IF PANIC BUTTON HIT
PANIC: CLR DURAT ;INDICATE END OF JOINT SERVOING
RTI
;DYNAMIC RESPONSE DATA STORAGE AREA
DR: .BLKW 500. ;FIRST TIME BUFFER OF DYNAMIC RESPONSE DATA
T2: .BLKW 500. ;SECOND TIME BUFFER
D1: .BLKW 500. ;FIRST DRIVE BUFFER
D2: .BLKW 500. ;SECOND DRIVE BUFFER
AG1: .BLKW 500. ;FIRST JOINT ANGLE BUFFER
.BLKW 500. ;SECOND JOINT ANGLE BUFFER
.BLKW 1000.
;BLUE ARM INTERFACE ADDRESSES
BLUE: 174000 ;DAC SAMPLE ADDRESS
174002 ;DAC CONTROL INFO ADDRESS
174004 ;A/D CONTROL INFO ADDRESS
174006 ;A/D SAMPLE ADDRESS
;YELLOW ARM INTERFACE ADDRESSES
YELO: 174000 ;DAC SAMPLE ADDRESS
174002 ;DAC CONTROL INFO ADDRESS
174004 ;A/D CONTROL INFO ADDRESS
174006 ;A/D SAMPLE ADDRESS
;DAC/ADC DATA
ADCCHN: .BYTE 21,14,15, 2, 3, 4, 5, 0
TACCHN: .BYTE 20,10,11, 6, 7, 0, 0, 0
DACCHN: .BYTE 1, 2, 3, 4, 5, 6, 7, 0
DACVAL: .BYTE 0, 0, 0, 0, 0, 0, 0, 0
.EVEN
;MINIMUM AND MAXIMUM JOINT ANGLE READINGS PERMITTED FOR JOINT IN WORKING RANGE
MINJT: -7777
-7777
-7777
-7777
-7777
-7777
-7777
MAXJT: 7777
7777
7777
7777
7777
7777
7777
;LOCAL VARIABLES
WRAP: -1 ;-1: LESS THAN 500 WORDS OF DR, 0: LESS THAN 1000 WORDS OF DR
; GT 0: MORE THAN 1000 WORDS OF DR, DATA WRAPS AROUND 2ND 500
DYNA: DR ;POINTER TO DYNAMIC RESPONSE DATA ARRAY
RUN: 0 ;FLAG INDICATING IF JOINT IN MOTION
NUMJT: 7 ;NUMBER OF DACS TO REFRESH
PDAC: 0 ;PTR TO PRESENT DAC BEING SERVICE
PVAL: 0 ;PTR TO PRESENT DAC VALUE TO WRITE
TACH: 0 ;TACH FEEDBACK BITS
THRE60: .WORD 42264,0 ;360.0
TO: 0
FROM: 0
MAXA: 0
TIME: 0 ;CURRENT TIME INTO MOTION
DBUF: .BLKW 300.
.END START